[JS / jQuery] Extra argument aan select voor redirect?

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb nu in mijn cms selects van deze vorm:
HTML:
1
2
3
4
5
6
<select class="goto">
  <option value="admin/content">Kies...</option>
  <option value="admin/content/add?page">page</option>
  <option value="admin/content/add?story">story</option>
  <option value="admin/content/add?image">image</option>
</select>

Ik heb een jQuery functie geschreven die bij elke pageload wordt geladen:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
/**
 * Essential tool: onselect, redirect the page to the chosen URL
 */
CMS.tools.selectGoto = function() {
  $('select.goto').change(function() {
    var selected = $("option:selected", this).val();
    if (selected != 'ignore') {
      document.location = selected;
    }
  });
}

Hoewel ik hier eerst tevreden mee was, wil ik er nu 2 zaken aan verbeteren:
  • de eerste option reload naar de huidige pagina, maar ik wil dat selectGoto de eerste optie (hier: kies...) negeert. Dan hoef ik er ook geen value meer aan toe te kennen
  • ik wil af van die lange URL's in elke option. Ik zit eraan te denken om een extra argument aan de select tag toe te voegen, iets als:
    HTML:
    1
    2
    3
    4
    5
    6
    
    <select class="goto" goto="admin/content/add?">
      <option>Kies...</option>
      <option value="page">page</option>
      <option value="story">story</option>
      <option value="image">image</option>
    </select>
  • In dat geval kan ik ook de class "goto" verwijderen. Ik kan de selectGoto dan laten checken of er selects met het goto-attribuut zijn en dan de functie attachen...
Een aantal vragen hierover:
  • mag je zomaar eigen attributen verzinnen? Ik heb het wel eens gezien hier en daar, maar echt compliant code is het natuurlijk niet
  • zo nee, heeft iemand een alternatief idee?
  • het schrijven van bovenstaande functie is even geleden en kostte me toen al veel tijd. Kent iemand de jQuery seelctor voor het geval je een eigen attribuut verzint? $('select.goto') levert immers de selects met als class "goto" op, niet selects met attribuut "goto"...
  • hoe laat ik mijn functie de eerste option (of: de options met een lege value) negeren?

[ Voor 9% gewijzigd door Verwijderd op 11-10-2009 20:46 ]


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Verwijderd schreef op zondag 11 oktober 2009 @ 20:43:
Een aantal vragen hierover:
  • mag je zomaar eigen attributen verzinnen? Ik heb het wel eens gezien hier en daar, maar echt compliant code is het natuurlijk niet
  • zo nee, heeft iemand een alternatief idee?
  • het schrijven van bovenstaande functie is even geleden en kostte me toen al veel tijd. Kent iemand de jQuery seelctor voor het geval je een eigen attribuut verzint? $('select.goto') levert immers de selects met als class "goto" op, niet selects met attribuut "goto"...
  • hoe laat ik mijn functie de eerste option (of: de options met een lege value) negeren?
Je pagina zal niet meer valideren, maar tenzij je alles als XHTML serveert (met de correcte content type, zodat de XML parser gebruikt wordt) zal geen enkele moderne browser er over vallen. Als je XHTML serveert met de correcte content type (ipv de fallback text/html) kun je altijd nog je eigen DTD gebruiken wat het goto attribuut op select tags definieert.

Om elk select element met een attribuut 'goto' te selecteren gebruik je:
JavaScript:
1
$("select[goto], document")


Wil je de options met een lege value negeren, dan wordt je selector:
JavaScript:
1
$("> option[value][value!='']", selectElement)


Deze laatste twee zijn overigens behoorlijk RTFM. Lees de jQuery API documentatie maar eens. Hoofdstukje 'Selectors' moet je hebben...

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 09:51

crisp

Devver

Pixelated

JavaScript:
1
if (selected != 'ignore')

Je hebt zelf toch al een optie ingebouwd om bepaalde opties te negeren (namelijk die met value="ignore") :?

HTML5 biedt overigens de mogelijkheid tot custom attributes in de vorm van data-xxx

Overigens zou ik dat url-part in een hidden form-field zetten, dan kan je er serverside ook nog wat mee voor de noodzakelijke non-JS fallback.

[ Voor 23% gewijzigd door crisp op 11-10-2009 23:16 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
crisp schreef op zondag 11 oktober 2009 @ 23:14:
Overigens zou ik dat url-part in een hidden form-field zetten, dan kan je er serverside ook nog wat mee voor de noodzakelijke non-JS fallback.
Dat vind ik een goed idee. Overigens heb ik inderdaad een ignore-filter, maar zat eraan te denken om de eerste optie helemaal geen value mee te geven. Lege value betekent "negeer" en vroeg me af of dat eleganter kon dan if (selected != ""). Anywaytjes, ik heb nu dit:
HTML:
1
2
3
4
5
6
<input type="hidden" name="edit[goto_type]" value="admin/content/add">
<select name="type" class="goto">
  <option value="ignore">Kies...</option>
  <option value="page">page</option>
  <option value="story">story</option>
</select>

De jQuery functie dient te zoeken naar selects met class "goto". Vervolgens wordt de name van die select gezocht (in dit geval "type"). Tenslotte wordt gezocht naar een hidden input met naam edit[goto_type]. De conventie is edit[goto_{name_van_select_met_class_goto}]. De valie van die hidden input moet worden gebruikt als redirect URL, iets als:
JavaScript:
1
2
3
4
5
6
7
8
9
CMS.tools.selectGoto = function() {
  $('select.goto').change(function() {
    var redirect_url = $("hidden.goto_" + this.name).val();
    var selected = $("option:selected", this).val();
    if (selected != "ignore") {
      document.location = redirect_url + "?" + selected;
    }
  });
}

Ik kom er alleen niet uit hoe de selector om de redirect_url te vinden, eruit moet zien. Wat ik heb, werkt niet. Kan iemand mij helpen?

[ Voor 8% gewijzigd door Verwijderd op 13-10-2009 14:43 ]


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 09:51

crisp

Devver

Pixelated

Je moet ook niet alles met selectors willen oplossen imo, dit zou ook gewoon moeten werken:

JavaScript:
1
var redirect_url = this.form.elements['goto_' + this.name].value;

(ervan uitgaande dat eea ook netjes in een <form> staat)

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
crisp schreef op dinsdag 13 oktober 2009 @ 14:51:
Je moet ook niet alles met selectors willen oplossen imo, dit zou ook gewoon moeten werken:
JavaScript:
1
var redirect_url = this.form.elements['goto_' + this.name].value;

(ervan uitgaande dat eea ook netjes in een <form> staat)
crisp, thanks! Ik ben alleen stom geweest; in werkelijkheid is de naam van de select ook van de vorm "edit[{name}]", alhier:
HTML:
1
2
<input type="hidden" name="edit[goto_type]" value="admin/content/add">
<select name="edit[type]" class="goto">

this.name is dus "edit[type]". Hoe kan ik hier makkelijk "edit[" en "]" vanaf filteren? Ik dacht eerst aan substr, maar de variabele naam (in dit geval "type") kan in lengte verschillen...

Ten tweede: als je gebruik maakt van een externe library zoals jQuery, is het dan niet netjes om zoveel mogelijk via die library te werken? Wat is jouw argument dat je zegt "je moet niet alles met selectors willen oplossen"?

Acties:
  • 0 Henk 'm!

  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
Verwijderd schreef op dinsdag 13 oktober 2009 @ 15:03:
Wat is jouw argument dat je zegt "je moet niet alles met selectors willen oplossen"?
Use the right tool for the right job.

Doet je backend nog iets met de edit-array met goto-type? Anders kan je die uit die array gooien.

JS-oplossing via indexOf().

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
moozzuzz schreef op dinsdag 13 oktober 2009 @ 15:25:
[...]
JS-oplossing via indexOf().
Ja, maar indexOf() heeft maar 2 argumenten: string waarbinnengezocht moet worden en de positie waar de substring wordt begonnen. Als "edit[type]" dan mijn string is, kan ik op z'n best "type]" retourneren. Daarna moet ik nog "]" verwijderen. Dan moet ik de lengte van de substring uitrekenen, en daar 1 vanaf halen om de startpositie te vinden voor een tweede ronde indexOf(). Kan dat niet eenvoudiger? Een manier om in 1 keer "edit[" en "]" van de string af te strippen?

Acties:
  • 0 Henk 'm!

  • moozzuzz
  • Registratie: Januari 2005
  • Niet online
Verwijderd schreef op dinsdag 13 oktober 2009 @ 15:45:
kan dat niet eenvoudiger? Een manier om in 1 keer "edit[" en "]" van de string af te strippen?
regex'en? Maar ik ben daar zelf niet zo'n guru in (en velen met mij :-). Overigens geeft je indexOf() inderdaad type] op en daar moet je dan één char vanaf doen, dus die tweede indexOf() is voor niets nodig :^)

JavaScript:
1
2
// pseudocode
stringetje.slice(indexOf(stringetje, "["),-1);

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Bedankt iedereen, ik heb er uiteindelijk dit van gemaakt:
JavaScript:
1
2
3
4
5
6
7
8
9
10
CMS.tools.selectGoto = function() {
  $('select.goto').change(function() {
    var name = this.name.substring(5, this.name.length - 1);
    var redirect = this.form.elements['edit[goto_' + name + ']'].value;
    var selected = $("option:selected", this).val();
    if (selected != 'ignore') {
      document.location = redirect + "?type=" + selected;
    }
  });
}

Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Verwijderd schreef op dinsdag 13 oktober 2009 @ 16:06:
Bedankt iedereen, ik heb er uiteindelijk dit van gemaakt
Ik zou je aanraden om jezelf aan te wennen in het name attribuut geen vreemde tekens zoals haakjes, komma's, vraagtekens, etc. te gebruiken aangezien het niet fijn werkt i.c.m. allerlei javascript frameworks.

Daarnast is het onder HTML4.01 overigens ook niet valide. Ik weet niet hoe het met XHTML gesteld is, maar ik kan me indenken dat daar vergelijkbare restricties gelden.

Zie ook de relevante passage in de specificatie voor HTML4.01:
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".")

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 09:51

crisp

Devver

Pixelated

R4gnax schreef op dinsdag 13 oktober 2009 @ 18:02:
[...]
Zie ook de relevante passage in de specificatie voor HTML4.01:

[...]
Je linkt naar de juiste passage maar je quote de verkeerde ;)
Het name-attribuut is van type CDATA (zie de DTD), en is dus geen NAME of ID-token ;)

Blokhaken zijn volledig valide in een name-attribuut; dat sommige frameworks het daardoor lastig te maken om ze te gebruiken in selectors is meer een beperking van dergelijke frameworks (of CSS selectors, hoewel je daar ook natuurlijk escaping kan toepassen). Zoals ik hierboven heb gedemonstreerd is er geen enkel probleem om dergelijke elementen via de elements collectie van het formulier aan te spreken (of zelfs via getElementsByName). Sterker nog: het is vele malen sneller dan dat gehannes met ingewikkelde selectors.

[ Voor 40% gewijzigd door crisp op 13-10-2009 18:57 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
crisp schreef op dinsdag 13 oktober 2009 @ 18:51:
[...]

Je linkt naar de juiste passage maar je quote de verkeerde ;)
Het name-attribuut is van type CDATA (zie de DTD), en is dus geen NAME of ID-token ;)
Nog eens gelezen en je hebt idd. gelijk. Dat krijg je als je al een uur naar die kaal geformatteerde specs hebt gekeken. De standaard W3C markup krijg je totaal schele ogen van.

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 09:51

crisp

Devver

Pixelated

R4gnax schreef op dinsdag 13 oktober 2009 @ 19:11:
[...]


Nog eens gelezen en je hebt idd. gelijk. Dat krijg je als je al een uur naar die kaal geformatteerde specs hebt gekeken. De standaard W3C markup krijg je totaal schele ogen van.
Gewoon uit je hoofd leren, hoef je er nooit meer naar te kijken B) :+

Intentionally left blank

Pagina: 1